package top.withwings.bonus.common.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.withwings.bonus.common.pojo.IndexedGrantedAuthority;
import top.withwings.bonus.common.pojo.User;
import top.withwings.bonus.common.repo.AuthorityRepo;
import top.withwings.bonus.common.repo.UserRepo;

import java.util.List;

@Service
public class UserService implements UserDetailsService {

    public final static String DEFAULT_PASSWORD = "000000";

    @Autowired private UserRepo userRepo;
    @Autowired private AuthorityRepo authorityRepo;

    @Override
    public User loadUserByUsername(String username) throws UsernameNotFoundException {

        User user = userRepo.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        List<IndexedGrantedAuthority> authorities = authorityRepo.findByUserId(user.getId());
        user.setAuthorities(authorities);
        return user;
    }


    public User findById(int userId){

        User user = userRepo.findById(userId);
        if (user == null) {
            return null;
        }
        user.erasePassword();
        List<IndexedGrantedAuthority> authorities = authorityRepo.findByUserId(user.getId());
        user.setAuthorities(authorities);
        return user;
    }

    @Transactional
    public void create(User user){

        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

        user.setPassword(bCryptPasswordEncoder.encode(DEFAULT_PASSWORD));

        user.setEnabled(true);

        int userId = userRepo.create(user);

        authorityRepo.addUserAuthority(userId,user.getAuthorities());

    }

    @Transactional
    public void delete(int userId){

        authorityRepo.deleteUserAuthority(userId);

        userRepo.delete(userId);

    }

    @Transactional
    public void update(User user){

        userRepo.update(user);

        authorityRepo.deleteUserAuthority(user.getId());

        authorityRepo.addUserAuthority(user.getId(),user.getAuthorities());

    }

    public List<User> findAll(){

        List<User> users = userRepo.findAll();

        for (User user : users) {
            user.setAuthorities(authorityRepo.findByUserId(user.getId()));
            user.erasePassword();
        }
        return users;

    }


}
